package com.sakura.springcloud.controller;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.sakura.springcloud.bean.CommonResult;
import com.sakura.springcloud.bean.ResponseCodeEnum;
import com.sakura.springcloud.dto.AuthDto;
import com.sakura.springcloud.jwt.JwtTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;


/**
 * @author BANGO
 */
@Slf4j
@RestController
@RequestMapping("/auth")
public class AuthController {

    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Resource
    JwtTokenUtil jwtTokenUtil;

    @PostMapping("/login")
    public CommonResult<Object> login(@RequestBody AuthDto authDto){
        Map<String, Object> returnMap = new HashMap<>();
        if (authDto.getId() == null){
            return CommonResult.error("请输入userID");
        }
        if (StringUtils.isBlank(authDto.getUserName())){
            return CommonResult.error("请输入用户名");
        }
        if (StringUtils.isBlank(authDto.getPassword())){
            return CommonResult.error("请输入密码");
        }

        String userName = authDto.getUserName();
        String id = authDto.getId();
        // 通过 jwtTokenUtil 生成 JWT 令牌和刷新令牌
        returnMap = jwtTokenUtil.generateTokenAndRefreshToken(String.valueOf(id), userName);
        log.info("获取到登录用户名：{}，id为：{}",userName,id);
        return CommonResult.success(returnMap);
    }


    /**
     * 刷新JWT令牌,用旧的令牌换新的令牌
     * 参数为需要刷新的令牌
     * header中携带刷新令牌
     */
    @GetMapping("/token/refresh")
    public CommonResult<Object> refreshToken(HttpServletRequest request, @RequestHeader(value = "${auth.jwt.header}") String token){

        String refreshToken = request.getHeader("refresh_token");
        if (StringUtils.isBlank(refreshToken)){
            return CommonResult.error("缺少参数");
        }
        token = refreshToken;

        if (StringUtils.isEmpty(token)) {
            return CommonResult.error(ResponseCodeEnum.TOKEN_MISSION.getCode(),
                    ResponseCodeEnum.TOKEN_MISSION.getMessage());
        }

        // 对Token解签名，并验证Token是否过期
        boolean isJwtNotValid = jwtTokenUtil.isTokenExpired(token);
        if(isJwtNotValid){
            return CommonResult.error(ResponseCodeEnum.TOKEN_INVALID.getCode(),
                    ResponseCodeEnum.TOKEN_INVALID.getMessage());
        }

        // 验证 token 里面的 userId 是否为空
        String userId = jwtTokenUtil.getUserIdFromToken(token);
        String username = jwtTokenUtil.getUserNameFromToken(token);
        if (StringUtils.isEmpty(userId)) {
            return CommonResult.error(ResponseCodeEnum.TOKEN_INVALID.getCode(),
                    ResponseCodeEnum.TOKEN_INVALID.getMessage());
        }

        // 这里为了保证 refreshToken 只能用一次，刷新后，会从 redis 中删除。
        // 如果用的不是 redis 中的 refreshToken 进行刷新令牌，则不能刷新。
        // 如果使用 redis 中已过期的 refreshToken 也不能刷新令牌。
        boolean isRefreshTokenNotExisted = jwtTokenUtil.isRefreshTokenNotExistCache(token);
        if(isRefreshTokenNotExisted){
            return CommonResult.error(ResponseCodeEnum.REFRESH_TOKEN_INVALID.getCode(),
                    ResponseCodeEnum.REFRESH_TOKEN_INVALID.getMessage());
        }

        //String us = jwtTokenUtil.getUserIdFromToken(token);
        Map<String, Object> tokenMap = jwtTokenUtil.refreshTokenAndGenerateToken(userId, username);

        return CommonResult.success( ResponseCodeEnum.SUCCESS.getMessage(),tokenMap);
    }


}

